package org.thukari.service;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.data.FormulaData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.metadata.WriteSheet;
import org.thukari.entity.CountData;
import org.thukari.entity.DealData;
import org.thukari.entity.MemberData;
import org.thukari.entity.OverAllData;

import java.util.*;

public class WriteOutService {
    Map<String, String> memberSerial = new HashMap<>();

    private Map<String, CountData> resultMap;
    private Map<String, DealData> concreteMap;
    private Map<String, CountData> memberMap;

    private void initMemberSerial() {
        this.memberSerial.put("张袁", "5774");
        this.memberSerial.put("彭雨婷", "30239");
        this.memberSerial.put("黄娟娟", "5773");
        this.memberSerial.put("高晶", "30201");
        this.memberSerial.put("王萌", "5771");
        this.memberSerial.put("胡逸文", "");
    }

    //TODO 是否跨月要做一个判断来专门处理
    public void writeOut(Map<String, CountData> resultMap, Map<String, DealData> concreteMap, Map<String, CountData> memberMap) {

        this.resultMap = resultMap;
        this.concreteMap = concreteMap;
        this.memberMap = memberMap;

        String fileName = System.getProperty("user.home") + "/Desktop/outList.xlsx";
        try (ExcelWriter excelWriter = EasyExcel.write(fileName).build()) {
            WriteSheet allSheet = EasyExcel.writerSheet(0, "测试").head(OverAllData.class).build();
            WriteSheet dealSheet = EasyExcel.writerSheet(1, "成交清单").head(DealData.class).build();
            WriteSheet memberSheet = EasyExcel.writerSheet(2, "中台人员").head(MemberData.class).build();

            initMemberSerial();

            writeAllSheet(resultMap, excelWriter, allSheet);
            writeDealSheet(concreteMap, excelWriter, dealSheet);
            writeMemberSheet(memberMap, excelWriter, memberSheet);
        }
    }

    private void writeMemberSheet(Map<String, CountData> memberMap, ExcelWriter excelWriter, WriteSheet memberSheet) {
        List<MemberData> memberDataList = new ArrayList<>();

        for (Map.Entry<String, CountData> entry : memberMap.entrySet()) {
            MemberData memberData = new MemberData();

            int todayTotal = 0;
            int monthTotal = 0;

            todayTotal += entry.getValue().getDataMap().get("当日").getFiber();
            todayTotal += entry.getValue().getDataMap().get("当日").getOther();
            monthTotal += entry.getValue().getDataMap().get("当月").getFiber();
            monthTotal += entry.getValue().getDataMap().get("当月").getOther();

            memberData.setSerial(memberSerial.get(entry.getKey()));
            memberData.setName(entry.getKey());
            memberData.setTodayDeliverNum(entry.getValue().getDataMap().get("当日").getOther());
            memberData.setTodayDirectNum(entry.getValue().getDataMap().get("当日").getFiber());
            memberData.setTodayNum(todayTotal);
            memberData.setTodayTotal(todayTotal);

            memberData.setMonthDeliverNum(entry.getValue().getDataMap().get("当月").getOther());
            memberData.setMonthDirectNum(entry.getValue().getDataMap().get("当月").getFiber());
            memberData.setMonthNum(monthTotal);
            memberData.setMonthTotal(monthTotal);

            memberData.setMonthDeal(entry.getValue().getStock());
            memberData.setMonthDealRate(memberData.getMonthTotal() != 0 ? (double) memberData.getMonthDeal() / memberData.getMonthTotal() : 0);

            memberDataList.add(memberData);


        }
        excelWriter.write(memberDataList, memberSheet);
    }

    private void writeAllSheet(Map<String, CountData> resultMap, ExcelWriter excelWriter, WriteSheet allSheet) {
        List<OverAllData> writeOutDataList = new ArrayList<>();

        int allTodayFiberNum = 0;
        int allTodayOtherNum = 0;
        int allTodayStockNum = 0;
        int allTodayTotal = 0;
        int allMonthFiberNum = 0;
        int allMonthOtherNum = 0;
        int allMonthStockNum = 0;
        int allMonthTotal = 0;
        int allDealFiberNum = 0;
        int allDealOtherNum = 0;
        int allDealStockNum = 0;
        int allDealNewTotal = 0;
        int allDealTotal = 0;

        for (Map.Entry<String, CountData> districtEntry : resultMap.entrySet()) {

            OverAllData overAllData = new OverAllData();

            overAllData.setDistrict(districtEntry.getKey());

            int todayTotal;
            int monthTotal;
            int dealTotal;

            todayTotal = districtEntry.getValue().getDataMap().get("当日").getFiber() + districtEntry.getValue().getDataMap().get("当日").getOther() + districtEntry.getValue().getDataMap().get("当日").getStock();

            overAllData.setTodayFiberNum(districtEntry.getValue().getDataMap().get("当日").getFiber());
            overAllData.setTodayOtherNum(districtEntry.getValue().getDataMap().get("当日").getOther());
            overAllData.setTodayStockNum(districtEntry.getValue().getDataMap().get("当日").getStock());
            overAllData.setTodayTotal(todayTotal);

            allTodayFiberNum += overAllData.getTodayFiberNum();
            allTodayOtherNum += overAllData.getTodayOtherNum();
            allTodayStockNum += overAllData.getTodayStockNum();
            allTodayTotal += overAllData.getTodayTotal();

            monthTotal = districtEntry.getValue().getDataMap().get("当月").getFiber() + districtEntry.getValue().getDataMap().get("当月").getOther() + districtEntry.getValue().getDataMap().get("当月").getStock();

            overAllData.setMonthFiberNum(districtEntry.getValue().getDataMap().get("当月").getFiber());
            overAllData.setMonthOtherNum(districtEntry.getValue().getDataMap().get("当月").getOther());
            overAllData.setMonthStockNum(districtEntry.getValue().getDataMap().get("当月").getStock());
            overAllData.setMonthTotal(monthTotal);

            allMonthFiberNum += overAllData.getMonthFiberNum();
            allMonthOtherNum += overAllData.getMonthOtherNum();
            allMonthStockNum += overAllData.getMonthStockNum();
            allMonthTotal += overAllData.getMonthTotal();

            dealTotal = districtEntry.getValue().getDataMap().get("成交").getFiber() + districtEntry.getValue().getDataMap().get("成交").getOther() + districtEntry.getValue().getDataMap().get("成交").getStock();

            overAllData.setDealFiberNum(districtEntry.getValue().getDataMap().get("成交").getFiber());
            overAllData.setDealOtherNum(districtEntry.getValue().getDataMap().get("成交").getOther());
            overAllData.setDealStockNum(districtEntry.getValue().getDataMap().get("成交").getStock());
            overAllData.setDealNewTotal(districtEntry.getValue().getDataMap().get("成交").getFiber() + districtEntry.getValue().getDataMap().get("成交").getOther());
            overAllData.setDealTotalNum(dealTotal);

            checkNum(overAllData);

            dealTotal = overAllData.getDealFiberNum() + overAllData.getDealOtherNum() + overAllData.getDealStockNum();
            overAllData.setDealNewTotal(overAllData.getDealFiberNum() + overAllData.getDealOtherNum());
            overAllData.setDealTotalNum(dealTotal);

            allDealFiberNum += overAllData.getDealFiberNum();
            allDealOtherNum += overAllData.getDealOtherNum();
            allDealStockNum += overAllData.getDealStockNum();
            allDealNewTotal += overAllData.getDealNewTotal();
            allDealTotal += overAllData.getDealTotalNum();

            overAllData.setDealFiberRate(overAllData.getMonthFiberNum() != 0 ? (double) overAllData.getDealFiberNum() / overAllData.getMonthFiberNum() : 0);
            overAllData.setDealOtherRate(overAllData.getMonthOtherNum() != 0 ? (double) overAllData.getDealOtherNum() / overAllData.getMonthOtherNum() : 0);
            overAllData.setDealNewTotalRate((overAllData.getMonthFiberNum() + overAllData.getMonthOtherNum()) != 0 ? (double) overAllData.getDealNewTotal() / (overAllData.getMonthFiberNum() + overAllData.getMonthOtherNum()) : 0);
            overAllData.setDealStockRate(overAllData.getMonthStockNum() != 0 ? (double) overAllData.getDealStockNum() / overAllData.getMonthStockNum() : 0);
            overAllData.setDealTotalRate(overAllData.getMonthTotal() != 0 ? (double) overAllData.getDealTotalNum() / overAllData.getMonthTotal() : 0);

            writeOutDataList.add(overAllData);
        }

        writeOutDataList = sortList(writeOutDataList);

        OverAllData overAllData = new OverAllData();

        overAllData.setDistrict("总计");

        overAllData.setTodayFiberNum(allTodayFiberNum);
        overAllData.setTodayOtherNum(allTodayOtherNum);
        overAllData.setTodayStockNum(allTodayStockNum);
        overAllData.setTodayTotal(allTodayTotal);

        overAllData.setMonthFiberNum(allMonthFiberNum);
        overAllData.setMonthOtherNum(allMonthOtherNum);
        overAllData.setMonthStockNum(allMonthStockNum);
        overAllData.setMonthTotal(allMonthTotal);

        overAllData.setDealFiberNum(allDealFiberNum);
        overAllData.setDealOtherNum(allDealOtherNum);
        overAllData.setDealStockNum(allDealStockNum);
        overAllData.setDealNewTotal(allDealNewTotal);
        overAllData.setDealTotalNum(allDealTotal);

        overAllData.setDealFiberRate(overAllData.getMonthFiberNum() != 0 ? (double) overAllData.getDealFiberNum() / overAllData.getMonthFiberNum() : 0);
        overAllData.setDealOtherRate(overAllData.getMonthOtherNum() != 0 ? (double) overAllData.getDealOtherNum() / overAllData.getMonthOtherNum() : 0);
        overAllData.setDealNewTotalRate((overAllData.getMonthFiberNum() + overAllData.getMonthOtherNum()) != 0 ? (double) overAllData.getDealNewTotal() / (overAllData.getMonthFiberNum() + overAllData.getMonthOtherNum()) : 0);
        overAllData.setDealStockRate(overAllData.getMonthStockNum() != 0 ? (double) overAllData.getDealStockNum() / overAllData.getMonthStockNum() : 0);
        overAllData.setDealTotalRate(overAllData.getMonthTotal() != 0 ? (double) overAllData.getDealTotalNum() / overAllData.getMonthTotal() : 0);

        writeOutDataList.add(overAllData);

        excelWriter.write(writeOutDataList, allSheet);
    }

    private void writeDealSheet(Map<String, DealData> concreteMap, ExcelWriter excelWriter, WriteSheet dealSheet) {
        List<DealData> dealDataList = new ArrayList<>();

        for (Map.Entry<String, DealData> dealDataEntry : concreteMap.entrySet()) {
            dealDataList.add(dealDataEntry.getValue());
        }

//        String fileName = "./backup/outList.xlsx";

        excelWriter.write(dealDataList, dealSheet);
    }

    private void checkNum(OverAllData overAllData) {
        if (overAllData.getMonthFiberNum() < overAllData.getDealFiberNum()) {
            int count = overAllData.getDealFiberNum() - overAllData.getMonthFiberNum();
            overAllData.setDealFiberNum(overAllData.getMonthFiberNum());
            changeDealMap(overAllData.getDistrict(), "宽带", count);
        }

        if (overAllData.getMonthOtherNum() < overAllData.getDealOtherNum()) {
            int count = overAllData.getDealOtherNum() - overAllData.getMonthOtherNum();
            overAllData.setDealOtherNum(overAllData.getMonthOtherNum());
            changeDealMap(overAllData.getDistrict(),"其它",count);
        }

        if (overAllData.getMonthStockNum() < overAllData.getDealStockNum()) {
            int count = overAllData.getDealStockNum() - overAllData.getMonthStockNum();
            overAllData.setDealStockNum(overAllData.getMonthStockNum());
            changeDealMap(overAllData.getDistrict(),"存量",count);
        }

        if ((overAllData.getMonthFiberNum() + overAllData.getMonthOtherNum()) < overAllData.getDealNewTotal()) {
            overAllData.setDealNewTotal(overAllData.getMonthFiberNum() + overAllData.getMonthOtherNum());
        }

        if (overAllData.getMonthTotal() < overAllData.getDealTotalNum()) {
            overAllData.setDealTotalNum(overAllData.getMonthTotal());
        }
    }

    private void changeDealMap(String district, String s, int count) {
        List<String> outList = new ArrayList<>();
        String type1,type2;
        switch (s) {
            case "宽带":
                type1 = "新装";
                type2 = "宽带";
                break;
            case "其它":
                type1 = "新装";
                type2 = "";
                break;
            case "存量":
                type1 = "存量";
                type2 = "";
                break;
            default:
                type1 = "";
                type2 = "";
        }
        int i = 0;
        for (Map.Entry<String, DealData> entry : concreteMap.entrySet()) {
            if (district.equals(entry.getValue().getDistrict())&&type1.equals(entry.getValue().getBusinessType())){
                outList.add(entry.getKey());
                i++;
            }
            if (i>=count){
                break;
            }
        }
        for (String s1:outList){
            concreteMap.remove(s1);
        }
    }

    private static List<OverAllData> sortList(List<OverAllData> writeOutDataList) {
        List<OverAllData> resultList = new ArrayList<>();
        List<String> districtList = new ArrayList<>(Arrays.asList("武昌", "洪山", "东湖高新", "江汉", "江岸", "汉阳", "硚口", "青山", "经开", "江夏", "新洲", "黄陂", "蔡甸", "东西湖", "长江新", "其它"));
        for (String name : districtList) {
            for (OverAllData writeOutData : writeOutDataList) {
                if (name.equals(writeOutData.getDistrict())) {
                    if (!name.equals("其它")) {
                        WriteCellData<String> writeCellData = new WriteCellData<>();
                        writeOutData.setDealRank(writeCellData);
                        FormulaData formulaData = new FormulaData();
                        writeCellData.setFormulaData(formulaData);
                        formulaData.setFormulaValue("=RANK(O" + (districtList.indexOf(name) + 5) + ",O$5:O$19)");
                        WriteCellData<String> writeCellData1 = new WriteCellData<>();
                        writeOutData.setDealTotalRank(writeCellData1);
                        FormulaData formulaData1 = new FormulaData();
                        writeCellData1.setFormulaData(formulaData1);
                        if (districtList.contains(name) && districtList.indexOf(name) <= 4) {
                            formulaData1.setFormulaValue("=RANK(T" + (districtList.indexOf(name) + 5) + ",T$5:T$9)");
                        } else if (districtList.indexOf(name) >= 5 && districtList.indexOf(name) <= 9) {
                            formulaData1.setFormulaValue("=RANK(T" + (districtList.indexOf(name) + 5) + ",T$10:T$14)");
                        } else {
                            formulaData1.setFormulaValue("=RANK(T" + (districtList.indexOf(name) + 5) + ",T$15:T$19)");
                        }
                    }

                    resultList.add(writeOutData);
                }
            }
        }
        return resultList;
    }
}
